<?php if (!defined('BASEPATH')) exit('No direct script access allowed'); 

class codexController extends Controller {
    var $display_fields = array();
    var $page_header = "";
    var $view_mode = "";
    var $controller_name = "";
    var $table = "";
    var $order_by = "";
    var $order_type = "";
    var $on_one_page = "";
    var $extra_uri_segments = "";
    var $table_access_restriction = array();

    var $add_link         ;     
    var $edit_link        ;     
    var $add_action       ;     
    var $edit_action      ;     
    var $delete_action    ;     
    var $controller_link  ;     

    function codexController () {
        Controller::Controller();
        $this->lang->load('codex');
        $this->load->vars(array('asset_folder' => $this->config->item('codex_asset_folder')));
        $this->load->model('codexmodel');

        $this->codextemplates->docType('strict');
        $this->codextemplates->setTitle($this->config->item('codex_default_title'));
        $this->codextemplates->rawHeaderHTML('<meta http-equiv="Content-Type" content="text/html;charset=utf-8">');
        $this->codextemplates->css('template-css','codex_default.css');

        $this->codextemplates->js('js-framework','jquery.js');
        $data['auto_generated_links'] = array();
        if($this->config->item('codex_auto_generate_crud')){
            $tables = $this->db->list_tables();
            foreach($tables as $table){
                if(!in_array($table,$this->config->item('codex_auto_generate_exclude_tables')))
                    $data['auto_generated_links'][$table] = '?c=crud&amp;m=index&amp;t='.$table;
            }
        }
        $this->codextemplates->loadView($this->config->item('codex_template_dir').'codex_header',$data);
    } 
    function _remap($method)
    {
        $this->$method();
    }
    function get_id($offset=3){
        if(!($id = $this->input->post($this->codexadmin->primary_key)))
            return $this->uri->segment($offset);
        return $id;
            
    }
    function setConfig($config){
         $this->table                    = (isset($config['db_table']))? $config['db_table'] : show_error($this->lang->line('codex_table_not_defined'));
         $this->form_setup               = (isset($config['form_setup']))? $config['form_setup'] : show_error($this->lang->line('codex_form_not_defined'));
         $this->controller_name          = (isset($config['controller_name']))? $config['controller_name'] : show_error($this->lang->line('codex_controller_not_defined'));
         $this->table_access_restriction = (isset($config['table_access_restriction']))? $config['table_access_restriction'] : array();

         $this->order_by                 = (isset($config['order_by']))? $config['order_by'] : "";
         $this->order_type               = (isset($config['order_type']))? $config['order_type'] : "";

         $this->page_header              = (array_key_exists('page_header',$config))? $config['page_header'] : $config['controller_name'];
         $this->view_mode                = isset($config['view_mode']) ? $config['view_mode'] : 'table';
         $this->display_fields           = isset($config['display_fields']) ? $config['display_fields'] : array_keys($config['form_setup']);

         $this->on_one_page              = isset($config['on_one_page']) ? $config['on_one_page'] : $this->config->item('codex_items_per_page');
         $this->first_item               = is_numeric($this->uri->segment(3)) ? (int)$this->uri->segment(3) : 0;

         $this->add_link                 = (isset($config['add_link']))? $config['add_link'] : strtolower($this->controller_name).'/add';
         $this->edit_link                = (isset($config['edit_link']))? $config['edit_link'] : strtolower($this->controller_name).'/manage/edit/{num}';
         $this->add_action               = (isset($config['add_action']))? $config['add_action'] : strtolower($this->controller_name).'/execute_add';
         $this->edit_action              = (isset($config['edit_action']))? $config['edit_action'] : strtolower($this->controller_name).'/execute_edit';
         $this->delete_action            = (isset($config['delete_action']))? $config['delete_action'] : strtolower($this->controller_name).'/manage';
         $this->controller_link          = (isset($config['controller_link']))? $config['controller_link'] : strtolower($this->controller_name);

         $this->codexcrumbs->add($this->config->item('index_page'),'Home');
         $this->codexcrumbs->add($this->controller_link,$this->page_header);
         $this->codexadmin->_initialize($config);
    }
    function index(){
        $this->codexcrumbs->add($this->controller_link,'Overview');

        /*
         * Setup the ordering
         */
        if(!$order_by = $this->input->post('order_by'))
            $order_by = ($this->order_by == "")? $this->codexadmin->primary_key : $this->order_by;

        if(!$order_type = $this->input->post('order_type'))
            $order_type = ($this->order_type == "")? 'desc' : $this->order_type;

        $this->db->orderby($order_by,$order_type);

        /*
         * Get the list of database fields. We do this because some plugins 
         * don't require a field in their db
         */
        $field_names = $this->event->trigger('getDbFields');
        
        // Because the primary_key isn't a field, we have to manually add it
        $field_names[0][] = $this->codexadmin->primary_key;
        $this->db->select(implode(',',$field_names[0]));

        //Apply any restrictions
        if(count($this->table_access_restriction) > 0) 
            foreach($this->table_access_restriction as $field=>$value)
                $this->db->where($field,$value);

        //Retrieve all the records
        $query = $this->db->get($this->table);
        $max_rows = $query->num_rows();

        $result = $query->result_array();
        //Split it up for pagination
        $result = array_slice($result,$this->first_item,$this->on_one_page);

        for($i=0;$i<count($result);$i++){
            //Update the active id
            $this->codexadmin->active_id = $result[$i][$this->codexadmin->primary_key];
            $db_data = $result[$i];
            $db_data = $this->event->trigger('prepForDisplay',array($db_data));
            $db_data = $db_data[0];

            //Unset all NULL values
            foreach($db_data as $name=>$value){
                if($value === NULL){
                    unset($db_data[$name]);
                }
            }

            if(isset($result[$i][$this->codexadmin->primary_key])) 
                $db_data[$this->codexadmin->primary_key] = $result[$i][$this->codexadmin->primary_key];

            $result[$i] = $db_data;
        }
            
         
        $data['add_link'] = $this->add_link;
        $data['entries'] = $result;
        $data['messages'] = $this->codexmessages->get();
        
        $this->load->library('pagination');

        $config = array();
        $config['base_url'] = site_url(strtolower($this->controller_name).'/index');
        $config['total_rows'] = $max_rows;
        $config['per_page'] = $this->on_one_page;
        $config['num_links'] = 2;
        $config['full_tag_open'] = '<div class="pagination-links">';
        $config['full_tag_close'] = '</div>';
        $config['first_link'] = 'First';
        $config['last_link'] = 'Last';

        $this->pagination->initialize($config);

        $this->codextemplates->loadView($this->config->item('codex_layout_dir').$this->view_mode,$data);
       

        $this->codextemplates->setTitle($this->page_header.$this->lang->line('codex_overview_title'));
        $this->codextemplates->printHTML();
    }
    function add($populate_form_with = array()){
        $this->codexcrumbs->add($this->uri->uri_string(),'Add');

        // Set an identifier for CSRF protection
        $this->codexsession->set_flashdata('form_id',$this->codexsession->userdata('user_id'));

        if(count($populate_form_with) > 0)
            $this->codexforms->populateWithArrayInfo($populate_form_with);

        //Get the list of users for permissions
        $query                          = $this->db->get('users');
        $permissions_data['user_list']  = $query->result_array();

        $data['form_html']              = $this->codexforms->getHTML();
        $data['permissions_form']       = $this->load->view($this->config->item('codex_template_dir').'codex_permissions_form',$permissions_data,true);
        $data['form_action']            = $this->add_action;

        $this->codextemplates->loadView($this->config->item('codex_template_dir').'codex_form_view',$data);

        $this->codextemplates->setTitle($this->lang->line('codex_add_title').$this->page_header);
        $this->codextemplates->printHTML();
    }
    function _edit($id,$populate_form_with = array()){
        $this->codexadmin->active_id = $id;
        $this->codexsession->set_flashdata('form_id',$this->codexsession->userdata('user_id'));

        $query = $this->db->get('users');
        $permissions_data['user_list'] = $query->result_array();
        $ownsership_result = $this->event->trigger('checkRecordOwnership',array('edit',$this->table,$id));

        if($ownsership_result[0] === false){
            redirect(str_replace('&amp;','&',$this->controller_link));
        }
        $this->codexcrumbs->add($this->uri->uri_string(),'Edit');

        $data = array();
        if(count($populate_form_with) > 0)
            $this->codexforms->populateWithArrayInfo($populate_form_with);
        else
            $this->codexforms->populateWithDbInfo($this->table,$id);

        $view_data['permissions_form'] = $this->load->view($this->config->item('codex_template_dir').'codex_permissions_form',$permissions_data,true);
        $view_data['form_html'] = $this->codexforms->getHTML();
        $view_data['form_action'] = $this->edit_action;

        $this->codextemplates->loadView($this->config->item('codex_template_dir').'codex_form_view',$view_data);
        $this->codextemplates->setTitle($this->lang->line('codex_edit_title').$this->page_header);
        $this->codextemplates->printHTML();
    }
    function delete($id=""){
        if($id === "")
            if(!($this->get_id()))
                show_error($this->lang->line('codex_invalid_id'));

        $this->_delete_selected_helper($id);
        redirect(str_replace('&amp;','&',$this->controller_link));
    }
    function execute_add(){
        if(!$this->codexadmin->matchFormAgainstId($this->codexsession->userdata('user_id')))
            show_error($this->lang->line('codex_form_ownership_error'));

        if(count($this->codexadmin->get_rules()) > 0){
            $this->codexvalidation->set_rules($this->codexadmin->get_rules());

            if($this->codexvalidation->run() == FALSE){
                $this->codexsession->keep_flashdata('form_id');

                $validation_errors = $this->codexmessages->get('form');
                $errors = array();

                foreach($validation_errors as $validation_error){
                    $parts = explode('|',$validation_error);
                    $errors[$parts[0]] = $parts[1];
                }

                $this->codexforms->setValidationErrors($errors);
                $this->add($_POST);
                return;
            }
        }

        $db_data = array();
        $this->event->trigger('preInsertHook');
        $db_data = $this->event->trigger('prepForDb',array($_POST));

        if(count($db_data) > 0)
            if($this->codexmodel->_add($this->table,$db_data[0])){

                $this->codexadmin->active_id        = $this->db->insert_id();
                $_POST[$this->codexadmin->primary_key]            = $this->codexadmin->active_id;
                $_POST['table']         = $this->table;
                $this->event->trigger('postInsertHook',array($_POST));

                $this->codexmessages->add('success',$this->codexadmin->get_message('add_success'));
                redirect(str_replace('&amp;','&',$this->controller_link));
            }
            else{
                $this->codexmessages->add('success',$this->codexadmin->get_message('add_failure'));
                redirect(str_replace('&amp;','&',$this->controller_link));
            }
    }
    function execute_edit(){
        if(!$this->codexadmin->matchFormAgainstId($this->codexsession->userdata('user_id')))
            show_error($this->lang->line('codex_form_ownership_error'));

        $id = $this->get_id();
        $this->codexadmin->active_id = $id;

        if(!(is_int($id) OR is_string($id))){
            show_error($this->lang->line('codex_invalid_id'));
        }

        if(count($this->codexadmin->get_rules()) > 0){
            $this->codexvalidation->set_rules($this->codexadmin->get_rules());
            if($this->codexvalidation->run() == FALSE){
                $this->codexsession->keep_flashdata('form_id');

                $validation_errors = $this->codexmessages->get('form');
                $errors = array();

                foreach($validation_errors as $validation_error){
                    $parts = explode('|',$validation_error);
                    $errors[$parts[0]] = $parts[1];
                }
                $this->codexforms->setValidationErrors($errors);
                $this->_edit($id,$_POST);
                return;
            }
        }

        $this->event->trigger('preEditHook',array($this->table,$id));
        $db_data = $this->event->trigger('prepForDb',array($_POST));

        if($this->codexmodel->_edit($this->table,$id,$db_data[0])){
            $this->event->trigger('postEditHook',array($db_data[0]));
            $this->codexmessages->add('success',$this->codexadmin->get_message('edit_success'));
            redirect(str_replace('&amp;','&',$this->controller_link));
        }
        else{
            $this->codexmessages->add('failure',$this->codexadmin->get_message('edit_failure'));
            redirect(str_replace('&amp;','&',$this->controller_link));
        }
    }
    function _delete_selected_helper($id){
        $table = $this->table;
        $this->codexadmin->active_id = $id;

        if(!$id){
            show_error($this->lang->line('codex_invalid_id'));
        }

        $query = $this->db->get_where('user_records',array('user_id'=>$this->codexsession->userdata('user_id'),
                                                           'record_id'=>$id));
        $result = $query->result_array();
        if(!(count($result) > 0 AND strpos($result[0]['permissions'],'owner') !== false)){
            $ownsership_result = $this->event->trigger('checkRecordOwnership',array('delete',$table,$id));
            if($ownsership_result[0] === false){
                redirect(str_replace('&amp;','&',$this->controller_link));
            }
        }

        if($this->event->trigger('preDeleteHook',array($table,$id))){
            $this->event->trigger('prepForDelete',array($table,$id));
            $this->codexmodel->delete($table,$id);
            $this->event->trigger('postDeleteHook',array($table,$id));

            if($this->db->affected_rows() != 1)
                return false;
            else
                return true;
        }
        return false;
    }
    function delete_confirm($id=""){
        if(!($id = $this->get_id()))
            show_error($this->lang->line('codex_invalid_id'));
        $data['id'] = $id;
        $data['form_action'] = strtolower($this->controller_name).'/delete'.$this->extra_uri_segments;
        $data['message'] = $this->codexadmin->get_message('delete_confirm');
        $data['link'] = $this->codexadmin->get_message('delete_confirm_link');
        
        $this->codextemplates->loadView($this->config->item('codex_template_dir').'codex_delete_confirm',$data);
        $this->codextemplates->printHTML();
    }
    function manage(){
        if($id = $this->input->post('edit'))
            return $this->_edit($id);

        else if($id = $this->input->post('delete'))
            return $this->delete_confirm($id);
        
        else if($id = $this->input->post('delete_selected')){
            $selected_rows = $this->input->post("selected_rows");

            if(is_array($selected_rows)){
                foreach($selected_rows as $id){
                    $this->_delete_selected_helper($id);
                }
            }

            $this->index();
        }
        else
            if($this->uri->segment(3) === "edit")
                return $this->_edit($this->get_id(4));
            else if($this->uri->segment(3) === "delete")
                return $this->delete_confirm($this->get_id(4));
            else
                redirect(str_replace('&amp;','&',$this->controller_link));
    }
    function pluginCallback (){ 
        $name = $this->uri->segment(3);
        $plugin = $this->input->post('plugin');
        $action = $this->input->post('action');
            
        $params = array();
        $params = explode(';',$this->input->post('params'));
        foreach($params as $k=>$param){
            $temp = explode(':',$param);
            $params[$temp[0]] = $temp[1];
            unset($params[$k]);
        }

        if(!class_exists($plugin))
            $this->codexforms->loadPlugin($plugin);

        $plugin_instance = new $plugin($name,$params);
        return $plugin_instance->$action();
    }
}
?>
